Skip to content

feat(terminal): detect localhost URLs in PTY output and show preview banner#278

Open
dcieslak19973 wants to merge 23 commits into
crynta:mainfrom
dcieslak19973:feat/terminal-localhost-url-banner
Open

feat(terminal): detect localhost URLs in PTY output and show preview banner#278
dcieslak19973 wants to merge 23 commits into
crynta:mainfrom
dcieslak19973:feat/terminal-localhost-url-banner

Conversation

@dcieslak19973
Copy link
Copy Markdown

Summary

When a process running in a terminal pane prints a localhost URL to stdout/stderr (e.g. npm run dev printing http://localhost:5173), a dismissible banner appears at the bottom of that pane with a clickable URL and an Open in Preview button that loads it in the built-in preview tab.

Changes

New files

  • src/modules/terminal/lib/url-detector.ts — pure function that decodes raw PTY bytes, strips ANSI escape sequences, and matches http(s)://localhost:PORT / http(s)://127.0.0.1:PORT URLs. Requires an explicit port. Flags OAuth-style redirect URLs (/callback, ?code=, etc.) for a distinct icon.
  • src/modules/terminal/LocalUrlBanner.tsx — absolute-positioned overlay rendered inside the terminal pane. Shows a Key01Icon (amber) for OAuth hints or Link01Icon (blue) for plain servers, the truncated URL, an Open in Preview button, and a dismiss button. Auto-dismisses after 30 s.

Modified files

  • useTerminalSession.ts — calls extractLocalhostUrls alongside deliverPtyBytes in the onData callback; per-session seenUrls: Set<string> prevents re-firing the same URL; onUrl callback added to Callbacks and Options types; seenUrls reset in respawnSession.
  • TerminalPane.tsx — wraps the xterm container in a relative div, manages banner state, passes onUrl to useTerminalSession, renders <LocalUrlBanner> overlay, accepts new onOpenUrl prop.
  • PaneTreeView.tsx / TerminalStack.tsxonOpenUrl threaded through the bundle chain (LeafBundle / Bundle types updated).
  • App.tsxonOpenUrl={(_, url) => openPreviewTab(url)} added to <TerminalStack>.

UX behaviour

  • Banner appears once per unique URL per terminal session (deduped via seenUrls)
  • Clicking the URL text or Open in Preview opens the URL in a preview tab and dismisses the banner
  • Banner auto-dismisses after 30 seconds
  • Respawning the session (e.g. after the process exits) resets seenUrls so the URL can surface again

dcieslak19973 and others added 22 commits May 15, 2026 17:24
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…RUD, search, grep

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ands

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…de tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… mod, profile cmd paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix russh API paths for Windows (keys::key::PublicKey, keys::load_secret_key)
- Fix profile_id serde rename to camelCase for frontend compat
- Fix pty flush: use interval timer so output isn't stuck in pending buffer
- Add ssh_home command to fetch remote home dir via exec
- Auto-reconnect last SSH profile on app startup, persisted via lastSshProfileId pref
- Connect SSH before fetching home dir in switchWorkspace

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…banner

When a process running in a terminal pane prints a URL of the form
http(s)://localhost:PORT or http(s)://127.0.0.1:PORT to stdout/stderr,
a dismissible banner appears at the bottom of that pane showing the URL
and an 'Open in Preview' button that loads the URL in the built-in
preview tab.

- url-detector.ts: pure function that strips ANSI escapes, matches
  localhost URLs (explicit port required), and flags OAuth-style
  redirect URLs
- useTerminalSession: wires extractLocalhostUrls into the onData path;
  per-session seenUrls Set prevents re-firing the same URL
- LocalUrlBanner: absolute-positioned overlay with auto-dismiss (30s),
  Key01Icon for OAuth hints, Link01Icon for plain servers
- TerminalPane: wraps xterm container in a relative div, manages banner
  state, accepts onOpenUrl prop
- PaneTreeView / TerminalStack: thread onOpenUrl down the bundle chain
- App: pass onOpenUrl to TerminalStack, calling openPreviewTab
Copilot AI review requested due to automatic review settings May 16, 2026 01:28
@dcieslak19973 dcieslak19973 requested a review from crynta as a code owner May 16, 2026 01:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant